﻿// // This code is released under the BSD license.
namespace PugLib.Extensions
{
	using System;
	using System.Drawing;
	using System.Windows.Forms;

	public static class PugExtensions
	{
		public static void DrawImage(this Control control, Image image)
		{
			using (Graphics g = control.CreateGraphics())
			{
				g.DrawImage(image, 0f, 0f, control.Width, control.Height);
			}
		}

		/// <summary>
		/// Simply wraps the boilerplate for invoking a control with a function and parameter.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="control"></param>
		/// <param name="action"></param>
		/// <param name="argument"></param>
		public static void BeginInvokeIfRequired<T>(this Control control, Action<T> action, T argument)
		{
			if (control.InvokeRequired)
			{
				control.BeginInvoke(action, argument);
			}
			else
			{
				action(argument);
			}
		}

		public static void InvokeIfRequired<T>(this Control control, Action<T> action, T argument)
		{
			if (control.InvokeRequired)
			{
				control.Invoke(action, argument);
			}
			else
			{
				action(argument);
			}
		}

		public static T InvokeIfRequired<T>(this Control control, Func<T> action, T argument)
		{
			if (control.InvokeRequired)
			{
				T rtn = (T) control.Invoke(action, argument);
				return rtn;
			}
			return action();
		}

		public static T InvokeIfRequired<T>(this Control control, Func<T> action)
		{
			if (control.InvokeRequired)
			{
				T rtn = (T) control.Invoke(action);
				return rtn;
			}
			return action();
		}

		public static DialogResult InvokeFormShowDialogIfRequired(this Form owner, Func<IWin32Window, DialogResult> childShowDialog)
		{
			if (owner.InvokeRequired)
			{
				DialogResult rtn = (DialogResult) owner.Invoke(childShowDialog, owner);
				return rtn;
			}
			return childShowDialog(owner);
		}

		public static void InvokeFormShowIfRequired(this Form owner, Action<IWin32Window> childShow)
		{
			if (owner.InvokeRequired)
			{
				owner.Invoke(childShow, owner);
				return;
			}
			childShow(owner);
		}


		/// <summary>
		/// Simply wraps the boilerplate for invoking a control with a function and parameter.
		/// </summary>
		/// <typeparam name="T1"></typeparam>
		/// <typeparam name="T2"></typeparam>
		/// <param name="control"></param>
		/// <param name="action"></param>
		/// <param name="arg1"></param>
		/// <param name="arg2"></param>
		public static void BeginInvokeIfRequired<T1, T2>(this Control control, Action<T1, T2> action, T1 arg1, T2 arg2)
		{
			if (control.InvokeRequired)
			{
				control.BeginInvoke(action, arg1, arg2);
			}
			else
			{
				action(arg1, arg2);
			}
		}

		/// <summary>
		/// Simply wraps the boilerplate for invoking a control with a function and parameter.
		/// </summary>
		/// <typeparam name="T1"></typeparam>
		/// <typeparam name="T2"></typeparam>
		/// <param name="control"></param>
		/// <param name="action"></param>
		/// <param name="arg1"></param>
		/// <param name="arg2"></param>
		public static void InvokeIfRequired<T1, T2>(this Control control, Action<T1, T2> action, T1 arg1, T2 arg2)
		{
			if (control.InvokeRequired)
			{
				control.Invoke(action, arg1, arg2);
			}
			else
			{
				action(arg1, arg2);
			}
		}


		/// <summary>
		/// Simply wraps the boilerplate for invoking a control with a function and parameter.
		/// </summary>
		/// <typeparam name="T1"></typeparam>
		/// <typeparam name="T2"></typeparam>
		/// <typeparam name="T3"></typeparam>
		/// <typeparam name="T4"></typeparam>
		/// <param name="control"></param>
		/// <param name="action"></param>
		/// <param name="arg1"></param>
		/// <param name="arg2"></param>
		/// <param name="arg3"></param>
		/// <param name="arg4"></param>
		public static void BeginInvokeIfRequired<T1, T2, T3, T4>(this Control control, Action<T1, T2, T3, T4> action,
		                                                         T1 arg1, T2 arg2, T3 arg3, T4 arg4)
		{
			if (control.InvokeRequired)
			{
				control.BeginInvoke(action, arg1, arg2, arg3, arg4);
			}
			else
			{
				action(arg1, arg2, arg3, arg4);
			}
		}

		/// <summary>
		/// /// Simply wraps the boilerplate for invoking a control with a function and parameter.
		/// </summary>
		/// <param name="control"></param>
		/// <param name="action"></param>
		public static void BeginInvokeIfRequired(this Control control, Action action)
		{
			if (control.InvokeRequired)
			{
				control.BeginInvoke(action);
			}
			else
			{
				action();
			}
		}


		/// <summary>
		/// /// Simply wraps the boilerplate for invoking a control with a function and parameter.
		/// </summary>
		/// <param name="control"></param>
		/// <param name="action"></param>
		public static void InvokeIfRequired(this Control control, Action action)
		{
			if (control.InvokeRequired)
			{
				control.Invoke(action);
			}
			else
			{
				action();
			}
		}
	}
}